package satk.database;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import satk.objetos.Persona;
import satk.beans.interfaces.IntControlManagerDB;
import satk.objetos.Institucion;

/**
 * <h3>ManagerPersona.java</h3>
 * <div><em>Fecha de creación: 27/04/2011, 05:54:30 PM.</em></div>
 * <p></p>
 * @author Sergio Flores Genis <sf.cancun@gmail.com>
 */
public class ManagerPersona extends DBManager
        implements IntControlManagerDB<Persona> {

    public ManagerPersona(java.sql.Connection c) {
        super(c);
    }

    public ManagerPersona() {
        super();
    }

    @Override
    public List<Persona> getAll() {
        String query = "SELECT * FROM persona NATURAL JOIN c_institucion ORDER BY id_persona DESC;";

        LinkedList<Persona> list = new LinkedList<Persona>();
        try {
            ResultSet r = this.select(query);
            while (r.next()) {
                Persona per = new Persona();

                // Datos de la persona
                int identificador = r.getInt("id_persona");
                String nombre = r.getString("nom_persona");
                String segNombre = r.getString("segnom_persona");
                String paterno = r.getString("pat_persona");
                String materno = r.getString("mat_persona");
                String sexo = r.getString("sex_persona");
                Date nac = r.getDate("fnac_persona");
                String boleta = r.getString("blta_persona");

                per.setIdentificador(identificador);
                per.setPrimerNombre(nombre);
                per.setSegundoNombre(segNombre);
                per.setPaterno(paterno);
                per.setMaterno(materno);
                per.setSexo(sexo);
                per.setNacimiento(nac);
                per.setBoleta(boleta);

                // Datos de la institución
                int idInst = r.getInt("idc_institucion");
                String sigInst = r.getString("sigc_institucion");
                String nomInst = r.getString("sigc_institucion");
                satk.objetos.Institucion inst;
                inst = new satk.objetos.Institucion(idInst, nomInst, sigInst);
                per.setInstitucion(inst);

                list.add(per);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.SEVERE,
                    "Error al obtener a las personas", ex);
        } catch (Exception ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.WARNING,
                    "Exepcion desconosida", ex);
        } finally {
            this.closeConexion();
        }
        return list;
    }

    @Override
    public Persona getById(long id) {
        String query = "SELECT * FROM persona WHERE (id_persona=?)"
                + "NATURAL JOIN c_institucion LIMIT 1;";
        Prepare parametros = new Prepare();
        parametros.add(id, Types.INTEGER);

        Persona per = null;
        try {
            ResultSet r = this.select(query);
            r.first();

            // Datos de la persona
            int identificador = r.getInt("id_persona");
            String nombre = r.getString("nom_persona");
            String segNombre = r.getString("segnom_persona");
            String paterno = r.getString("pat_persona");
            String materno = r.getString("mat_persona");
            String sexo = r.getString("sex_persona");
            Date nac = r.getDate("fnac_persona");
            String boleta = r.getString("blta_persona");


            // Datos de la institución
            int idInst = r.getInt("idc_institucion");
            String sigInst = r.getString("sigc_institucion");
            String nomInst = r.getString("sigc_institucion");
            satk.objetos.Institucion inst;
            inst = new satk.objetos.Institucion(idInst, nomInst, sigInst);

            per = new Persona();
            per.setIdentificador(identificador);
            per.setPrimerNombre(nombre);
            per.setSegundoNombre(segNombre);
            per.setPaterno(paterno);
            per.setMaterno(materno);
            per.setSexo(sexo);
            per.setNacimiento(nac);
            per.setBoleta(boleta);
            per.setInstitucion(inst);

        } catch (SQLException ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.SEVERE,
                    "Error al obtener a las personas", ex);
        } catch (Exception ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.WARNING,
                    "Exepcion desconosida", ex);
        } finally {
            this.closeConexion();
        }
        return per;
    }

    public Persona getByBoleta(String boleta) {
        String query = "SELECT * FROM persona NATURAL JOIN c_institucion WHERE (blta_persona=?) LIMIT 1;";
        Prepare parametros = new Prepare();
        parametros.add(boleta, Types.VARCHAR);

        Persona per = null;
        try {
            ResultSet r = this.select(query, parametros);
            r.first();

            // Datos de la persona
            int identificador = r.getInt("id_persona");
            String nombre = r.getString("nom_persona");
            String segNombre = r.getString("segnom_persona");
            String paterno = r.getString("pat_persona");
            String materno = r.getString("mat_persona");
            String sexo = r.getString("sex_persona");
            Date nac = r.getDate("fnac_persona");
            String pboleta = r.getString("blta_persona");


            // Datos de la institución
            int idInst = r.getInt("idc_institucion");
            String sigInst = r.getString("sigc_institucion");
            String nomInst = r.getString("sigc_institucion");
            satk.objetos.Institucion inst;
            inst = new satk.objetos.Institucion(idInst, nomInst, sigInst);

            per = new Persona();
            per.setIdentificador(identificador);
            per.setPrimerNombre(nombre);
            per.setSegundoNombre(segNombre);
            per.setPaterno(paterno);
            per.setMaterno(materno);
            per.setSexo(sexo);
            per.setNacimiento(nac);
            per.setBoleta(pboleta);
            per.setInstitucion(inst);

        } catch (SQLException ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.SEVERE,
                    "Error al obtener a las personas", ex);
        } catch (Exception ex) {
            Logger.getLogger(ManagerInstitucion.class.getName()).log(Level.WARNING,
                    "Exepcion desconosida", ex);
        } finally {
            this.closeConexion();
        }
        return per;
    }

    @Override
    public int add(Persona o) throws SQLException {
        String query = "INSERT INTO persona ("
                + "clvreg_persona, nom_persona, segnom_persona, pat_persona, "
                + "mat_persona, sex_persona, fnac_persona, blta_persona, idc_institucion) "
                + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
        Prepare p = new Prepare(9);
        p.setStringTransform(Prepare.STRING_CAPITAL);
        p.add(o.getBoleta(), Types.VARCHAR);
        p.add(o.getPrimerNombre(), Types.VARCHAR);
        p.add(o.getSegundoNombre(), Types.VARCHAR);
        p.add(o.getPaterno(), Types.VARCHAR);
        p.add(o.getMaterno(), Types.VARCHAR);
        p.add(o.getSexo(), Types.VARCHAR);
        p.add(o.getNacimiento(), Types.DATE);
        p.add(o.getBoleta(), Types.VARCHAR);
        p.add(o.getInstitucion().getIdentificador(), Types.INTEGER);

        int resp = this.edit(query.toString(), p);
        o.setIdentificador(getLastIdInsert());
        Institucion inst = new ManagerInstitucion(getConexion()).getById(o.getInstitucion().getIdentificador());
        o.setInstitucion(inst);
        this.closeConexion();
        return resp;
    }

    @Override
    public int update(Persona o, Persona n) throws SQLException {
        DBManager.PrepareUpdate parametros = new DBManager.PrepareUpdate(3);
        if (!n.getPrimerNombre().equals(o.getPrimerNombre())) {
            parametros.add("nom_persona", n.getPrimerNombre(), Types.VARCHAR);
        }
        if (!n.getSegundoNombre().equals(o.getSegundoNombre())) {
            parametros.add("segnom_persona", n.getSegundoNombre(), Types.VARCHAR);
        }
        if (!n.getPaterno().equals(o.getPaterno())) {
            parametros.add("pat_persona", n.getPaterno(), Types.VARCHAR);
        }
        if (!n.getMaterno().equals(o.getMaterno())) {
            parametros.add("mat_persona", n.getMaterno(), Types.VARCHAR);
        }
        if (!n.getSexo().equals(o.getSexo())) {
            parametros.add("sex_persona", n.getSexo(), Types.VARCHAR);
        }
        if (!n.getNacimiento().equals(o.getNacimiento())) {
            parametros.add("fnac_persona", n.getNacimiento(), Types.DATE);
        }
        if (!n.getBoleta().equals(o.getBoleta())) {
            parametros.add("blta_persona", n.getBoleta(), Types.VARCHAR);
        }
        if (!n.getIdentificador().equals(o.getIdentificador())) {
            parametros.add("idc_institucion", n.getIdentificador(), Types.INTEGER);
        }
        if (parametros.getPrepare().isEmpty()) {return -2;}
        String query = String.format("UPDATE persona %s WHERE (id_persona = ?);",
                parametros.getSet());
        parametros.getPrepare().add(n.getIdentificador(), Types.INTEGER);

        int resp = this.edit(query, parametros.getPrepare());
        this.closeConexion();
        return resp;
    }

    @Override
    public int remove(Persona o) throws SQLException {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
